package fw.asmx.materialdesign.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;

import fw.asmx.materialdesign.R;

public class FreshableRecyclerView extends FrameLayout
{
    public FreshableRecyclerView(Context context)
    {
        super(context);
        initView();
    }

    public FreshableRecyclerView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        initView();
    }

    public FreshableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public FreshableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
                                 int defStyleRes)
    {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    public SwipeRefreshLayout swipeRefreshLayout;
    public RecyclerView recyclerView;

    private RecyclerView.LayoutManager layoutManager;

    private OnFreshListener onFreshListener;
    private OnLoadMoreListener onLoadMoreListener;

    private boolean isLoadMoreOpen = false;

    private void initView()
    {
        View v = LayoutInflater.from(getContext())
                               .inflate(R.layout.freshable_recyclerview, this);
        swipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe);
        recyclerView = (RecyclerView) v.findViewById(R.id.rv);
        //
        swipeRefreshLayout.setDistanceToTriggerSync(400);
        //
    }

    /**
     * Set RecyclerView's Adapter
     * @param adapter RecyclerView.Adapter
     */
    public void setAdapter(RecyclerView.Adapter adapter)
    {
        recyclerView.setAdapter(adapter);
    }

    /**
     * Set RecyclerView's LayoutManager
     * @param layoutManager LayoutManager
     */
    public void setLayoutManager(RecyclerView.LayoutManager layoutManager)
    {
        this.layoutManager = layoutManager;
    }

    /**
     * Set refresh spinner's color.
     * @param clrs color's array.
     */
    public void setFreshSignColor(int... clrs)
    {
        swipeRefreshLayout.setColorSchemeResources(clrs);
    }

    @Deprecated
    public void enableLoadMore()
    {
        isLoadMoreOpen = true;
    }

    @Deprecated
    public void disableLoadMore()
    {
        isLoadMoreOpen = false;
    }

    /**
     * Enable fresh operation.
     */
    public void enableFresh()
    {
        swipeRefreshLayout.setEnabled(true);
    }

    /**
     * Disable fresh operation
     * @param triggerStop whether trigger stopFresh() method.
     */
    public void disableFresh(boolean triggerStop)
    {
        swipeRefreshLayout.setRefreshing(false);
        if (triggerStop && onFreshListener != null)
        {
            onFreshListener.onFreshStop();
        }
        swipeRefreshLayout.setEnabled(false);
    }

    /**
     * Start refresh if current is not refreshing
     */
    public void startFresh()
    {
        if(!swipeRefreshLayout.isRefreshing())
        {
            swipeRefreshLayout.setRefreshing(true);
        }
    }

    /**
     * Stop refresh if current is refreshing
     */
    public void stopFresh()
    {
        swipeRefreshLayout.setRefreshing(false);
        if (onFreshListener != null && swipeRefreshLayout.isRefreshing())
        {
            onFreshListener.onFreshStop();
        }
    }

    /**
     * Get RecyclerView's item count.
     * @return item count
     */
    public int getItemCount()
    {
        return layoutManager == null ? 0 : layoutManager.getItemCount();
    }

    @Deprecated
    public int findFirstVisibleItemPosition()
    {
        final View child = findOneVisibleChild(0, layoutManager.getChildCount(), false, true);
        return child == null ? RecyclerView.NO_POSITION :
                recyclerView.getChildAdapterPosition(child);
    }

    @Deprecated
    public int findFirstCompletelyVisibleItemPosition()
    {
        final View child = findOneVisibleChild(0, layoutManager.getChildCount(), true, false);
        return child == null ? RecyclerView.NO_POSITION :
                recyclerView.getChildAdapterPosition(child);
    }

    @Deprecated
    public int findLastVisibleItemPosition()
    {
        final View child = findOneVisibleChild(layoutManager.getChildCount() - 1, -1, false, true);
        return child == null ? RecyclerView.NO_POSITION :
                recyclerView.getChildAdapterPosition(child);
    }

    @Deprecated
    public int findLastCompletelyVisibleItemPosition()
    {
        final View child = findOneVisibleChild(layoutManager.getChildCount() - 1, -1, true, false);
        return child == null ? RecyclerView.NO_POSITION :
                recyclerView.getChildAdapterPosition(child);
    }

    @Deprecated
    View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible,
                             boolean acceptPartiallyVisible)
    {
        OrientationHelper helper;
        if (layoutManager.canScrollVertically())
        {
            helper = OrientationHelper.createVerticalHelper(layoutManager);
        }
        else
        {
            helper = OrientationHelper.createHorizontalHelper(layoutManager);
        }

        final int start = helper.getStartAfterPadding();
        final int end = helper.getEndAfterPadding();
        final int next = toIndex > fromIndex ? 1 : -1;
        View partiallyVisible = null;
        for (int i = fromIndex; i != toIndex; i += next)
        {
            final View child = layoutManager.getChildAt(i);
            final int childStart = helper.getDecoratedStart(child);
            final int childEnd = helper.getDecoratedEnd(child);
            if (childStart < end && childEnd > start)
            {
                if (completelyVisible)
                {
                    if (childStart >= start && childEnd <= end)
                    {
                        return child;
                    }
                    else if (acceptPartiallyVisible && partiallyVisible == null)
                    {
                        partiallyVisible = child;
                    }
                }
                else
                {
                    return child;
                }
            }
        }
        return partiallyVisible;
    }

    @Deprecated
    public void setOnLoadMoreListener(final OnLoadMoreListener onLoadMoreListener)
    {
        this.onLoadMoreListener = onLoadMoreListener;
        recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener()
        {
            @Override public void onLoadMore(int currentPage)
            {
                onLoadMoreListener.onLoadMore(currentPage);
            }
        });
    }

    /**
     * Set RecyclerView's Fresh Listener
     * @param onFreshListener
     */
    public void setOnFreshListener(final OnFreshListener onFreshListener)
    {
        this.onFreshListener = onFreshListener;

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
        {
            @Override public void onRefresh()
            {
                if (onFreshListener != null)
                {
                    onFreshListener.onFreshStart();
                }
            }
        });
    }

    public interface OnFreshListener
    {
        void onFreshStart();

        void onFreshStop();
    }

    public interface OnLoadMoreListener
    {
        void onLoadMore(int currentPage);
    }
}
